1   /*
2    * Copyright (C) 2011 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License.  You may obtain a copy
6    * of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  
17  package com.google.common.base;
18  
19  import static com.google.common.base.Preconditions.checkNotNull;
20  
21  import com.google.common.annotations.Beta;
22  import com.google.common.annotations.GwtCompatible;
23  
24  import java.io.Serializable;
25  
26  import javax.annotation.Nullable;
27  
28  /**
29   * Equivalence applied on functional result.
30   *
31   * @author Bob Lee
32   * @since 10.0
33   */
34  @Beta
35  @GwtCompatible
36  final class FunctionalEquivalence<F, T> extends Equivalence<F>
37      implements Serializable {
38  
39    private static final long serialVersionUID = 0;
40  
41    private final Function<F, ? extends T> function;
42    private final Equivalence<T> resultEquivalence;
43  
44    FunctionalEquivalence(
45        Function<F, ? extends T> function, Equivalence<T> resultEquivalence) {
46      this.function = checkNotNull(function);
47      this.resultEquivalence = checkNotNull(resultEquivalence);
48    }
49  
50    @Override protected boolean doEquivalent(F a, F b) {
51      return resultEquivalence.equivalent(function.apply(a), function.apply(b));
52    }
53  
54    @Override protected int doHash(F a) {
55      return resultEquivalence.hash(function.apply(a));
56    }
57  
58    @Override public boolean equals(@Nullable Object obj) {
59      if (obj == this) {
60        return true;
61      }
62      if (obj instanceof FunctionalEquivalence) {
63        FunctionalEquivalence<?, ?> that = (FunctionalEquivalence<?, ?>) obj;
64        return function.equals(that.function)
65            && resultEquivalence.equals(that.resultEquivalence);
66      }
67      return false;
68    }
69  
70    @Override public int hashCode() {
71      return Objects.hashCode(function, resultEquivalence);
72    }
73  
74    @Override public String toString() {
75      return resultEquivalence + ".onResultOf(" + function + ")";
76    }
77  }